/**
 * create by zhangpu
 * date:2015年3月2日
 */
package com.acooly.module.openapi.client.provider.fuiou;

import com.acooly.module.openapi.client.api.AbstractApiServiceClient;
import com.acooly.module.openapi.client.api.exception.ApiClientException;
import com.acooly.module.openapi.client.api.exception.ApiServerException;
import com.acooly.module.openapi.client.api.marshal.ApiMarshal;
import com.acooly.module.openapi.client.api.marshal.ApiUnmarshal;
import com.acooly.module.openapi.client.api.transport.Transport;
import com.acooly.module.openapi.client.provider.fuiou.domain.FuiouNotify;
import com.acooly.module.openapi.client.provider.fuiou.domain.FuiouRequest;
import com.acooly.module.openapi.client.provider.fuiou.domain.FuiouResponse;
import com.acooly.module.openapi.client.provider.fuiou.marshall.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Map;

/**
 * ApiService执行器
 *
 * @author zhangpu
 */
@Component("fuiouApiServiceClient")
public class FuiouApiServiceClient
        extends AbstractApiServiceClient<FuiouRequest, FuiouResponse, FuiouNotify, FuiouResponse> {

    private static Logger logger = LoggerFactory.getLogger(FuiouApiServiceClient.class);

    public static final String PROVIDER_NAME = "fuiou";

    @Resource(name = "fuiouHttpTransport")
    private Transport transport;
    @Resource(name = "fuiouRequestMarshall")
    private FuiouRequestMarshall requestMarshal;
    @Resource(name = "fuiouRedirectMarshall")
    private FuiouRedirectMarshall redirectMarshal;
    @Autowired
    private FuiouResponseUnmarshall responseUnmarshal;
    @Autowired
    private FuiouNotifyUnmarshall notifyUnmarshal;
    @Autowired
    private FuiouReturnUnmarshall returnUnmarshal;

    @Autowired
    private OpenAPIClientFuiouProperties openAPIClientFuiouProperties;

    @Override
    public FuiouResponse execute(FuiouRequest request) {
        try {
            beforeExecute(request);
            String url = openAPIClientFuiouProperties.getCanonicalUrl(openAPIClientFuiouProperties.getGateway(), request.getService() + ".action");
            String requestMessage = getRequestMarshal().marshal(request);
            String responseMessage = getTransport().exchange(requestMessage, url);
            FuiouResponse t = getResponseUnmarshal().unmarshal(responseMessage, request.getService());
            afterExecute(t);
            return t;
        } catch (ApiServerException ose) {
            logger.error("服务器:" + ose.getMessage(), ose);
            throw ose;
        } catch (ApiClientException oce) {
            logger.error("客户端:" + oce.getMessage(), oce);
            throw oce;
        } catch (Exception e) {
            logger.error("内部错误:" + e.getMessage(), e);
            throw new ApiClientException("内部错误:" + e.getMessage());
        }
    }

    @Override
    public String redirectGet(FuiouRequest request) {
        try {
            String requestMessage = getRedirectMarshal().marshal(request);
            return openAPIClientFuiouProperties.getCanonicalUrl(getRedirectGateway(), request.getService() + ".action") + "?"
                    + requestMessage;
        } catch (ApiServerException ose) {
            logger.warn("服务器错误:" + ose.getMessage(), ose);
            throw ose;
        } catch (ApiClientException oce) {
            logger.warn("客户端异常:" + oce.getMessage(), oce);
            throw oce;
        } catch (Exception e) {
            logger.warn("内部错误:" + e.getMessage(), e);
            throw new ApiClientException("内部错误:" + e.getMessage());
        }
    }

    @Override
    protected String getRedirectGateway() {
        return openAPIClientFuiouProperties.getGateway();
    }

    @Override
    protected ApiMarshal<String, FuiouRequest> getRequestMarshal() {
        return this.requestMarshal;
    }

    @Override
    protected ApiUnmarshal<FuiouResponse, String> getResponseUnmarshal() {
        return this.responseUnmarshal;
    }

    @Override
    protected ApiMarshal<String, FuiouRequest> getRedirectMarshal() {
        return this.redirectMarshal;
    }

    @Override
    protected ApiUnmarshal<FuiouNotify, Map<String, String>> getNoticeUnmarshal() {
        return this.notifyUnmarshal;
    }

    @Override
    protected Transport getTransport() {
        return this.transport;
    }


    public ApiUnmarshal<FuiouResponse, Map<String, String>> getReturnUnmarshal() {
        return this.returnUnmarshal;
    }

    @Override
    public String getName() {
        return PROVIDER_NAME;
    }
}
